package com.example.demo.rabbitMQ.listener;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;

/**
 * Package : com.example.demo.rabbitMQ
 * Description : TODO
 * Create on : 2019/1/28 15:20 星期一
 *
 * @author Xingli.Li
 * @version v1.0.0
 * 修改历史:
 * 修改人 | 修改日期 | 修改描述
 * -------------------------------------------
 **/
@ConditionalOnProperty(prefix = "rabbitmq", name = "enable", havingValue = "true")
@Component
public class RabbitMQListener {

    /**
     * 接收消息,消费者
     *
     * @param text
     */
    @RabbitListener(queues = "directqueue1")//监听指定队列的消息
    @RabbitHandler
    public void receiveDirectQueue(String sendMsg, Channel channel, Message message) {
        System.out.println("点对点监听器1号收到消息" + sendMsg);
    }

    @RabbitListener(queues = "topicqueue1")
    @RabbitHandler
    public void receiveTopicQueue(String sendMsg, Channel channel, Message message) {
        System.out.println("组播监听器1收到消息方法1" + sendMsg);
    }

    @RabbitListener(queues = "topicqueue1")//监听指定队列的消息
    @RabbitHandler
    public void receiveTopicQueue2(String sendMsg, Channel channel, Message message) {
        System.out.println("组播监听器1收到消息方法2" + sendMsg);
    }

    /**
     * @param sendMsg
     * @param channel
     * @param message
     * @Queue：当所有消费客户端断开连接后，是否自动删除队列： true：删除，false:不删除。
     * @Exchange:当所有绑定队列都不在使用时，是否自动删除交换器： true：删除，false：不删除。
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${spring.rabbitmq.queue}", autoDelete = "fasle"),
            exchange = @Exchange(value = "${spring.rabbitmq.exchange}", type = ExchangeTypes.FANOUT)),
            containerFactory = "devContainerFactory")
    @RabbitHandler
    public void receiveFanoutQueue(String sendMsg, Channel channel, Message message) {
        System.out.println("广播监听器1收到消息方法1" + sendMsg);
    }

    /**
     * 手动确认,监听
     *
     * @param sendMsg
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitListener(queues = "fanoutQueue1")
    @RabbitHandler
    public void receiveFanoutQueue1(String sendMsg, Channel channel, Message message) throws IOException {
        System.out.println("广播监听器收到队列1的消息方法" + sendMsg);
    }

    /**
     * 手动确认,监听
     *
     * @param sendMsg
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitListener(queues = "fanoutQueue")
    @RabbitHandler
    public void receiveFanoutQueue2(String sendMsg, Channel channel, Message message) throws IOException {
        System.out.println("广播监听器收到消息方法2" + sendMsg);
        try {
            /**
             * 手动确认一条消息：<br>
             * channel.basicAck(deliveryTag, false); <br>
             * deliveryTag:该消息的index <br>
             * multiple：是否批量.true:将一次性ack所有小于deliveryTag的消息 <br>
             */
            // 自动确认机制情况下,会报unknown delivery tag
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            // 如果开启事务,则需要事务提交
            // channel.txCommit();
            // 回滚事务
            // channel.txRollback();
        } catch (Exception e) {
            //消费者处理出了问题，需要告诉队列信息消费失败
            /**
             * 拒绝确认消息:<br>
             * channel.basicNack(long deliveryTag, boolean multiple, boolean requeue) ; <br>
             * deliveryTag:该消息的index<br>
             * multiple：是否批量.true:将一次性拒绝所有小于deliveryTag的消息。<br>
             * requeue：被拒绝的是否重新入队列 <br>
             */
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                    false, true);
            /**
             * 拒绝一条消息：<br>
             * channel.basicReject(long deliveryTag, boolean requeue);<br>
             * deliveryTag:该消息的index<br>
             * requeue：被拒绝的是否重新入队列
             */
            //channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }

    }


}
